import json
import logging
import threading
import time
from typing import Dict, Any, List, Optional

from app.core.messaging import rabbitmq_client, MessageType
from app.api.endpoints.chat import manager as websocket_manager
from app.db.database import SessionLocal
from app.crud import chat as chat_crud

logger = logging.getLogger(__name__)

class MessageService:
    """消息处理服务，处理RabbitMQ中的消息"""
    
    def __init__(self):
        """初始化消息服务"""
        self.running = False
        self.threads = []
    
    def start(self):
        """启动消息处理服务"""
        if self.running:
            logger.warning("Message service is already running")
            return
        
        self.running = True
        
        # 启动消息消费线程
        chat_thread = threading.Thread(
            target=self._consume_chat_messages,
            daemon=True
        )
        chat_thread.start()
        self.threads.append(chat_thread)
        
        notification_thread = threading.Thread(
            target=self._consume_notifications,
            daemon=True
        )
        notification_thread.start()
        self.threads.append(notification_thread)
        
        logger.info("Message service started")
    
    def stop(self):
        """停止消息处理服务"""
        self.running = False
        rabbitmq_client.close()
        logger.info("Message service stopped")
    
    def _consume_chat_messages(self):
        """消费聊天消息"""
        def callback(ch, method, properties, body):
            try:
                message_data = json.loads(body)
                logger.debug(f"Received chat message: {message_data}")
                
                # 处理聊天消息
                chat_id = message_data.get('chat_id')
                if not chat_id:
                    logger.error("Chat message without chat_id")
                    ch.basic_ack(delivery_tag=method.delivery_tag)
                    return
                
                # 将消息通过WebSocket发送给聊天参与者
                self._send_message_to_participants(chat_id, message_data)
                
                ch.basic_ack(delivery_tag=method.delivery_tag)
            except Exception as e:
                logger.error(f"Error processing chat message: {e}")
                ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False)
        
        rabbitmq_client.consume_messages(MessageType.CHAT_MESSAGE, callback)
    
    def _consume_notifications(self):
        """消费通知消息"""
        def callback(ch, method, properties, body):
            try:
                notification_data = json.loads(body)
                logger.debug(f"Received notification: {notification_data}")
                
                # 处理通知
                user_ids = notification_data.get('user_ids', [])
                content = notification_data.get('content')
                
                if content:
                    # 创建系统通知
                    db = SessionLocal()
                    try:
                        messages = chat_crud.create_system_notification(db, content=content, user_ids=user_ids)
                        
                        # 通过WebSocket发送通知
                        for message in messages:
                            participant = chat_crud.get_chat_participant(db, message.chat_id, message.user_id)
                            if participant:
                                self._send_notification_to_user(participant.user_id, {
                                    'id': message.id,
                                    'content': message.content,
                                    'created_at': message.created_at.isoformat()
                                })
                    finally:
                        db.close()
                
                ch.basic_ack(delivery_tag=method.delivery_tag)
            except Exception as e:
                logger.error(f"Error processing notification: {e}")
                ch.basic_reject(delivery_tag=method.delivery_tag, requeue=False)
        
        rabbitmq_client.consume_messages(MessageType.NOTIFICATION, callback)
    
    async def _send_message_to_participants(self, chat_id: int, message_data: Dict[str, Any]):
        """将消息发送给聊天参与者"""
        # 获取聊天参与者
        db = SessionLocal()
        try:
            participants = chat_crud.get_chat_participants(db, chat_id)
            sender_id = message_data.get('sender_id')
            
            # 通过WebSocket发送消息
            for participant in participants:
                if participant.user_id != sender_id:  # 不发送给发送者自己
                    await websocket_manager.send_personal_message(
                        message_data,
                        participant.user_id,
                        chat_id
                    )
        finally:
            db.close()
    
    async def _send_notification_to_user(self, user_id: int, notification_data: Dict[str, Any]):
        """将通知发送给用户"""
        # 系统通知使用特殊的chat_id，为了简化这里使用0
        await websocket_manager.send_personal_message(
            notification_data,
            user_id,
            0  # 系统通知的chat_id，实际应用中应该是系统通知聊天的ID
        )

# 创建消息服务单例
message_service = MessageService() 